//--------------------------------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
//--------------------------------------------------------------------
//Copyright (c) 2001 - 2008 by Lattice Semiconductor Corporation
//--------------------------------------------------------------------
//Permission:
//Lattice Semiconductor grants permission to use this code for use
//in synthesis for any Lattice programmable logic product. Other
//use of this code, including the selling or duplication of any
//portion is strictly prohibited.
//Disclaimer:
//This VHDL or Verilog source code is intended as a design reference
//which illustrates how these types of functions can be implemented.
//It is the user's responsibility to verify their design for
//consistency and functionality through the use of formal
//verification methods. Lattice Semiconductor provides no warranty
//regarding the use or functionality of this code.
//--------------------------------------------------------------------
//Lattice Semiconductor Corporation
//5555 NE Moore Court
//Hillsboro, OR 97214
//U.S.A
//TEL: 1-800-Lattice (USA and Canada)
//503-268-8001 (other locations)
//web: http://www.latticesemi.com/
//email: techsupport@latticesemi.com
//--------------------------------------------------------------------
//Code Revision History :
//--------------------------------------------------------------------
//Ver: |  Author  |Mod. Date   |Changes Made:
//V1.0 |  D.WANG  |10/15/2012  |Initial Creation
//V1.1 |  D.Wang  |12/10/2012  |Updated based on Avermedia's spec
//--------------------------------------------------------------------
//
// *** This Control & Status Register is meant for external host, different
// *** from the internal Extension Register for Audio and Video data packet
// -------------------------------------------------------------------
// -- Register Map
// -------------------------------------------------------------------
// Address | Register       | Bits | Default | Descriptions
// ==============================================================================
// 0x00    | FW_VER         | 7:0  | TBD     | FPGA Build Revision
//         | (R/O)          |      |         | 
// ------------------------------------------------------------------------------
// 0x01    | IN_RES         | 7:0  | 0x00    | Input Video Resoulution
//         | (W/R)          |      |         | 0x00 : 1920x1080
//         |                |      |         | 0x01 : 1280x720
//         |                |      |         | 0x02~0xFF : Reserved
// ------------------------------------------------------------------------------
// 0x02    | OUT_RES        | 7:0  | 0x00    | Output Video Resoulution
//         | (W/R)          |      |         | 0x00 : 1920x1080
//         |                |      |         | 0x01 : 1280x720
//         |                |      |         | 0x02~0xFF : Reserved
// ------------------------------------------------------------------------------
// 0x03    | Dimension      | 7:4  | 0x0     | Dimension mode
//         | (W/R)          |      |         | 0x0  : 2D
//         |                |      |         | 0x1  : 3D, Left | Right
//         |                |      |         | 0x2  : 3D, Overlap Frame
//         |                |      |         | 0x3 ~ 0xF : Reserved
//         |                |------|---------|-----------------------------------
//         |                | 3:0  | 0x0     | Scale mode
//         |                |      |         | 0x0  : NO
//         |                |      |         | 0x1  : YES
//         |                |      |         | 0x2 ~ 0xF : Reserved
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// 0x10    | SPI 1 Control  | 7:0  | 0x00    | Control Register for SPI 1
//         | (W/R)          |      |         |
// ------------------------------------------------------------------------------
// 0x11    | SPI 1 Address  | 7:0  | 0x00    | SPI 1 Address Register
//         | (W/R)          |      |         |
// ------------------------------------------------------------------------------
// 0x12    | SPI 1 Data     | 7:0  | 0x00    | SPI 1 Data Register
//         | (W/R)          |      |         |
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// 0x20    | SPI 2 Control  | 7:0  | 0x00    | Control Register for SPI 2
//         | (W/R)          |      |         |
// ------------------------------------------------------------------------------
// 0x21    | SPI 2 Address  | 7:0  | 0x00    | SPI 2 Address Register
//         | (W/R)          |      |         |
// ------------------------------------------------------------------------------
// 0x22    | SPI 2 Data     | 7:0  | 0x00    | SPI 2 Data Register
//         | (W/R)          |      |         |
// ------------------------------------------------------------------------------

module i2c_config_reg (
    input  wire         clk
   ,input  wire         rstn

   // Control & Status signals from the scale

   // Control signals to the scale,
   ,output wire  [8 -1: 0]   input_resoulution
   ,output wire  [8 -1: 0]   output_resoulution
   ,output wire  [4 -1: 0]   scale_mode
   ,output wire  [4 -1: 0]   dimension_mode

   ,output wire  [8 -1: 0]   spi1_ctrl
   ,output wire  [8 -1: 0]   spi1_addr
   ,output wire  [8 -1: 0]   spi1_wdata
   ,output wire  [8 -1: 0]   spi2_ctrl
   ,output wire  [8 -1: 0]   spi2_addr
   ,output wire  [8 -1: 0]   spi2_wdata

   // I2C interface
   ,input  wire         scl
   ,input  wire         sda_in
   ,output wire         sda_oe
   );
   
   // I2C Configure Register Parameter Settings
   parameter DEVICE_ID       = 7'h10;  //*** Important Note: I2C Read/Write Address = {DEVICE_ID, R/W bit}, 8'h20 for write, 8'h21 for read
   parameter OE_DELAY_CYCLE  = 8'h08;
   parameter REVISION_NUM    = 8'h10;   // revision 1.0
   
   // I2C backend interface signals
   wire [7:0] addr_int;
   reg  [7:0] rdata_int;
   wire [7:0] wdata_int;
   wire       wen_int;
   wire       mstr_rd_done;
   wire [6:0] dev_id;
   
   // Contro & Status Registers
   reg  [8 -1: 0]   csr_input_resoulution;
   reg  [8 -1: 0]   csr_output_resoulution;
   reg  [4 -1: 0]   csr_scale_mode;
   reg  [4 -1: 0]   csr_dimension_mode;
   reg  [8 -1: 0]   csr_spi1_ctrl;
   reg  [8 -1: 0]   csr_spi1_addr;
   reg  [8 -1: 0]   csr_spi1_wdata;
   reg  [8 -1: 0]   csr_spi1_rdata;
   reg  [8 -1: 0]   csr_spi2_ctrl;
   reg  [8 -1: 0]   csr_spi2_addr;
   reg  [8 -1: 0]   csr_spi2_wdata;
   reg  [8 -1: 0]   csr_spi2_rdata;

   // *** I2C Read data from internal Configure Registers
   always @(*) begin
      case (addr_int)
         8'h00 : rdata_int <= REVISION_NUM;
         8'h01 : rdata_int <= csr_input_resoulution;
         8'h02 : rdata_int <= csr_output_resoulution;
         8'h03 : rdata_int <= {csr_dimension_mode, csr_scale_mode};

         8'h10 : rdata_int <= csr_spi1_ctrl;
         8'h11 : rdata_int <= csr_spi1_addr;
         8'h12 : rdata_int <= csr_spi1_rdata;

         8'h20 : rdata_int <= csr_spi2_ctrl;
         8'h21 : rdata_int <= csr_spi2_addr;
         8'h22 : rdata_int <= csr_spi2_rdata;
         default : rdata_int <= 8'hEE;
      endcase
   end
                    
   // 0x01 ~ 0x06, 0x10 register write operation
   always @(negedge rstn or posedge clk) begin
      if (~rstn) begin
         csr_input_resoulution <= 8'h00;
         //8'h00: 1080P><8'h01: 720P
         csr_output_resoulution <= 8'h00;
         {csr_dimension_mode, csr_scale_mode} <= 8'h11; 
         //8'h00: 2D,NoScale><8'h11: 3DLR,Scale><8'h20: 3DO,Scale

         csr_spi1_ctrl <= 8'h00;
         csr_spi1_addr <= 8'h00;
         csr_spi1_wdata <= 8'h00;

         csr_spi2_ctrl <= 8'h00;
         csr_spi2_addr <= 8'h00;
         csr_spi2_wdata <= 8'h00;
      end
      else begin
         if (wen_int) begin
            case (addr_int)
               8'h01 : csr_input_resoulution <= wdata_int;
               8'h02 : csr_output_resoulution <= wdata_int;
               8'h03 : {csr_dimension_mode, csr_scale_mode} <= wdata_int;

               8'h10 : csr_spi1_ctrl <= wdata_int;
               8'h11 : csr_spi1_addr <= wdata_int;
               8'h12 : csr_spi1_wdata <= wdata_int;

               8'h20 : csr_spi2_ctrl <= wdata_int;
               8'h21 : csr_spi2_addr <= wdata_int;
               8'h22 : csr_spi2_wdata <= wdata_int;
            endcase
         end
      end
   end
   
  assign input_resoulution = csr_input_resoulution;
  assign output_resoulution = csr_output_resoulution;
  assign scale_mode = csr_scale_mode;
  assign dimension_mode = csr_dimension_mode;

  assign spi1_ctrl = csr_spi1_ctrl; 
  assign spi1_addr = csr_spi1_addr;
  assign spi1_wdata = csr_spi1_wdata;
  assign spi2_ctrl = csr_spi2_ctrl; 
  assign spi2_addr = csr_spi2_addr;
  assign spi2_wdata = csr_spi2_wdata;


   // *** Instantiate I2C Slave controller module
   i2c_slave #(DEVICE_ID,OE_DELAY_CYCLE) i2c_slv_cntl(
  .rstn        ( rstn     ),
  .sys_clk     ( clk      ),
  .rd_continue ( 1'b0     ),
  .rd_num      ( 8'h01    ),
  .scl         ( scl      ),
  .sda         ( sda_in   ),
  .sda_oe      ( sda_oe   ),
  .dev_id      ( dev_id   ),
  .reg_addr    ( addr_int ),
  .rd_data     ( rdata_int),
  .wr_data     ( wdata_int),
  .wr_en       ( wen_int  ),
  .mstr_rd_done( mstr_rd_done)
  );
  
endmodule
